home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
tc_tsr10.zip
/
PRTSC.C
< prev
next >
Wrap
Text File
|
1991-06-18
|
15KB
|
371 lines
/*--------------------------------------------------------------------------*
| PrtSc.C |
| contains screen, printer, keyboard, and disk I/O routines |
| PrtSC.c is supplied as is with no warranty, expressed or implied. |
| It is not copyrighted, either. |
*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*
| Author: |
| Sherif El-Kassas . :. |
| EB dept \_____o__/ __________ |
| Eindhoven U of Tec .. / |
| The Netherlands / Email: elkassas@eb.ele.tue.nl |
*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*
| The author shall not be liable to the user for any direct, indirect |
| or consequential loss arising from the use of, or inability to use, |
| any program or file howsoever caused. No warranty is given that the |
| programs will work under all circumstances. |
*--------------------------------------------------------------------------*/
#include <dos.h>
#include <bios.h>
#include <fcntl.h>
#include <stat.h>
#include <io.h>
#include <stdlib.h>
#include "prtsc.h"
/*------------------------------------------------------------------------*
| GLOBAL VARIABLES |
*------------------------------------------------------------------------*/
unsigned screen_pos = 0; /* pointer to the current screen location */
char far *screen = (char far *) 0xB8000000L; /* pointer to video RAM */
/* assume (for now) we have a colored monitor ! */
char far * save_buffer; /* pointer to a buffer that is used to save */
/* box borders. (save_buffer is declared as a */
/* far pointer to make sure that it's compatible */
/* with the screen pointer */
char box_buffer[((MAX_X+1)*2+(MAX_Y+1)*2)*2]; /* reserve the maximum amount */
/* of memory needed to save */
/* the rubber-band box */
byte old_cursor_color; /* to save cursor location */
int old_cursor_pos; /* and attribute */
/*------------------------------------------------------------------------*
| Initialize screen and buffer pointers |
*------------------------------------------------------------------------*/
void initialize_video(void){
union REGS reg;
reg.h.ah = 0x0F; /* interrupt 0x10 function 0x0F get current */
int86(0x10, ®, ®); /* display mode. if al==7 i.e. mono screen */
if (reg.h.al == 7) /* change the value of the screen pointer */
screen = (char far *) 0xB0000000L;
save_buffer = MK_FP(_DS, (unsigned) box_buffer); /* point to box buffer*/
old_cursor_pos = 0;
old_cursor_color = screen[1];
}/* initialize_video() */
/*------------------------------------------------------------------------*
| Read a key using BIOS function (interrupt 0x16 function 0) |
*------------------------------------------------------------------------*/
int getkey(void){
register int c;
c = bioskey(0);
return( (c&0x00ff) ? (c & 0x00ff) : c );
} /* getkey() */
/*------------------------------------------------------------------------*
| Move inverse video cursor to col and row. |
*------------------------------------------------------------------------*/
void move_cursor( byte col, byte row ){
screen[old_cursor_pos+1] = old_cursor_color; /* restore old color */
old_cursor_pos = row*160+col*2; /* save cursor position */
old_cursor_color = screen[old_cursor_pos+1]; /* save color */
/* screen[old_cursor_pos+1] = CURSOR_COLOR; /* put cursor at col and row */
if(screen[old_cursor_pos+1]==CURSOR_COLOR)
screen[old_cursor_pos+1] = CURSOR_COLOR1;
else screen[old_cursor_pos+1] = CURSOR_COLOR;
}/* move_cursor */
/*------------------------------------------------------------------------*
| Make col and row the current screen position |
*------------------------------------------------------------------------*/
void gotoxy( byte col, byte row ){
screen_pos = row*((MAX_X+1)*2)+col*2;
}/* gotoxy */
/*------------------------------------------------------------------------*
| Write character and attribute at current location and move pointer |
*------------------------------------------------------------------------*/
void putc(char c, byte color){
screen[screen_pos] = c; /* write character */
screen_pos++; /* point to color location */
screen[screen_pos] = color;/* write color */
screen_pos++; /* point to next position */
}/* putc */
/*------------------------------------------------------------------------*
| Write character and attribute "num" times |
*------------------------------------------------------------------------*/
void repeat_char(char c, register int num, byte color){
register int i;
for(i=0;i<num;i++) putc(c, color);
}/* repeat_char */
/*------------------------------------------------------------------------*
| Write string |
*------------------------------------------------------------------------*/
void puts(register char *p, byte color){
while (*p) putc(*p++, color);
}/* puts */
/*------------------------------------------------------------------------*
| Copy data from far source to far destination |
*------------------------------------------------------------------------*/
void move( char far *src, char far *dest, int amount ){
register int i;
for (i=0; i<amount; i++) dest[i] = src[i];
}/* move */
/*------------------------------------------------------------------------*
| Copy data from/to the screen |
*------------------------------------------------------------------------*/
void scr_move( char far *screen, char far *buffer,
unsigned amount,
byte direction )
{
if (direction == SAVE)
move( screen, buffer, amount );
else move( buffer, screen, amount );
}/* scr_move */
/*------------------------------------------------------------------------*
| Exchange two bytes |
*------------------------------------------------------------------------*/
void exchange(byte *a, byte *b){
int temp;
temp = *a; *a = *b; *b = temp;
}/* exchange */
/*------------------------------------------------------------------------*
| Order two bytes |
*------------------------------------------------------------------------*/
void order( byte *a, byte *b){
if (*a > *b)
exchange( a, b );
}/* order */
/*------------------------------------------------------------------------*
| Save/Restore the box defined by sx, sy, lx, ly to/from buff |
*------------------------------------------------------------------------*/
void box_move( byte sx, byte sy, byte lx, byte ly,
char far *buff,
byte direction )
{
int y, x, i;
order( &sy, &ly );
x = min(sx, lx);
i = (abs(lx-sx)+1) << 1;
scr_move( &screen[(160*sy)+(2*x)], &buff[0], i, direction);
scr_move( &screen[(160*ly)+(2*x)], &buff[i], i, direction);
i <<= 1;
for (y = sy+1; y<ly; y++){
scr_move( &screen[(160*y)+(2*sx)], &buff[i], 2, direction);
i += 2;
scr_move( &screen[(160*y)+(2*lx)], &buff[i], 2, direction);
i += 2;
}
}/* box_move */
/*------------------------------------------------------------------------*
| Draw box |
*------------------------------------------------------------------------*/
void draw_box( byte sx, byte sy, byte lx, byte ly ){
byte x, y;
order( &sy, &ly );
x = min(sx,lx);
if (sx != lx ){
gotoxy(x, sy);
putc(C1, BOX_COLOR); repeat_char(H, abs(lx-sx)-1, BOX_COLOR);
putc(C2, BOX_COLOR);
gotoxy(x, ly);
putc(C3, BOX_COLOR); repeat_char(H, abs(lx-sx)-1, BOX_COLOR);
putc(C4, BOX_COLOR);
}
for (y = sy+1; y <ly; y++){
gotoxy(sx, y); putc(V, BOX_COLOR); gotoxy(lx, y); putc(V, BOX_COLOR);
}
}/* draw_box */
/*------------------------------------------------------------------------*
| Get box corr. |
*------------------------------------------------------------------------*/
void get_box_corr(byte *x1, byte *y1, byte *x2, byte *y2){
byte quit, band_on;
byte x, y;
int key;
old_cursor_pos = 0;
old_cursor_color = screen[1];
band_on = FALSE; quit = FALSE;
x = y = 0;
do{
if (!band_on) move_cursor(x,y);
key = getkey();
if (band_on) box_move( *x1, *y1, x, y, save_buffer, RESTORE );
switch( key ){
case UP: y -= (y > MIN_Y);
break;
case DOWN: y += (y < MAX_Y);
break;
case RIGHT: x += (x < MAX_X);
break;
case LEFT: x -= (x > MIN_X);
break;
case HOME: y -= (y>MIN_Y);
x -= (x > MIN_X);
break;
case END: x -= (x > MIN_X);
y += (y < MAX_Y);
break;
case PGDN: y += (y < MAX_Y);
x += (x < MAX_X);
break;
case PGUP: y -= (y > MIN_Y);
x += (x < MAX_X);
break;
case CTRL_RIGHT: x = MAX_X;
break;
case CTRL_LEFT: x = MIN_X;
break;
case CTRL_HOME: x = MIN_X; y = MIN_Y;
break;
case CTRL_END: x = MIN_X; y = MAX_Y;
break;
case CTRL_PGUP: x = MAX_X; y = MIN_Y;
break;
case CTRL_PGDN: x = MAX_X; y = MAX_Y;
break;
case ENTER: if (band_on){
*x2 = x; *y2 = y;
quit = TRUE;
}
else{
band_on = TRUE;
*x1 = x; *y1 = y;
}
break;
case ESC: band_on = FALSE;
break;
}
if (band_on){
box_move( *x1, *y1, x, y, save_buffer, SAVE );
draw_box( *x1, *y1, x, y);
}
}while (!quit);
if (band_on) box_move( *x1, *y1, x, y, save_buffer, RESTORE );
screen[old_cursor_pos+1] = old_cursor_color;
if (*x1 > *x2) exchange(x1, x2);
if (*y1 > *y2) exchange(y1, y2);
}/* get_box_corr */
/*------------------------------------------------------------------------*
| Yes. return TRUE if y is pressed |
*------------------------------------------------------------------------*/
int yes(char *prompt){
register key;
scr_move( screen, save_buffer, (MAX_X+1)*2, SAVE );
gotoxy(0,0); puts(prompt, ON_COLOR);
key = getkey(); putc( key, ON_COLOR);
scr_move( screen, save_buffer, (MAX_X+1)*2, RESTORE );
return( (key=='y') || (key=='Y') );
}/* yes */
/*------------------------------------------------------------------------*
| Print a character (using interrupt 0x17) |
*------------------------------------------------------------------------*/
void printc(char c){
union REGS reg;
reg.h.ah = 0;
reg.h.al = c;
reg.x.dx = 0;
int86( 0x17, ®, ® );
}/* printc */
/*------------------------------------------------------------------------*
| Print contents of screen (x1, y1) (x2, y2) |
*------------------------------------------------------------------------*/
void print_screen( byte x1, byte y1, byte x2, byte y2 ){
register x, y;
if (yes("DO YOU WANT TO PRINT THE CURRENT SCREEN ? (Y/N)"))
{
gotoxy(0,0);
for ( y = y1; y <= y2; y++){
for ( x = x1; x <= x2; x++){
printc(screen[y*160+x*2]);
}
printc(13); printc(10);
}
}
}/* print_screen */
/*------------------------------------------------------------------------*
| Save contents of screen (x1, y1)-(x2, y2) |
*------------------------------------------------------------------------*/
void save_screen( byte x1, byte y1, byte x2, byte y2 ){
static char *file_name = "OUTPUT.PRN";
static int handle = -1;
static char temp[MAX_X+1];
register x,y;
if ( yes("DO YOU WANT TO SAVE THE CURRENT SCREEN ? (Y/N)") )
{
handle = open(file_name, O_WRONLY|O_APPEND|O_CREAT, S_IREAD|S_IWRITE);
if (handle > -1){
for ( y = y1; y <= y2; y++){
for (x=x1; x<=x2; x++)
temp[x-x1] = screen[y*160+x*2];
temp[x-x1] = 13;
temp[x-x1+1] = 10;
_write(handle, temp, x2-x1+3);
}
close(handle);
}
}
}/* save_screen */
/*------------------------------------------------------------------------*
| Main task |
*------------------------------------------------------------------------*/
void main_task(void){
byte x1, y1, x2, y2;
old_cursor_pos = 0;
old_cursor_color = screen[1];
get_box_corr(&x1, &y1, &x2, &y2);
print_screen( x1, y1, x2, y2 );
save_screen( x1, y1, x2, y2 );
}/* main_task */